package com.ysd.service.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysd.service.bean.ClockInteractionBean;
import com.ysd.service.dao.ClockDao;
import com.ysd.service.entity.Clock;
import com.ysd.service.util.MqttMessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.SQLOutput;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class ClockService extends ServiceImpl<ClockDao, Clock> {

    private ConcurrentHashMap<String, Long> lastMessageTimeMap = new ConcurrentHashMap<>();

    @Autowired
    private MqttMessageUtil mqttMessageUtil;

    @Autowired
    private ClockDao clockDao;

    /**
     * 根据登录用户查询用户绑定的所有闹钟设备
     * @param openid
     * @return
     */
    public List<Clock> queryClocksByUser(String openid){
        LambdaQueryWrapper<Clock> queryWrapper = Wrappers.lambdaQuery(Clock.class);
        queryWrapper.eq(Clock::getOpenId, openid);
        queryWrapper.eq(Clock::getDelFlag, 0);
        queryWrapper.orderByAsc(Clock::getCreateDate);
        return clockDao.selectList(queryWrapper);
    }

    /**
     * 查询闹钟详情
     * @param clockId
     * @return
     */
    public Clock queryClocksDetail(String clockId){
        return clockDao.selectById(clockId);
    }

    /**
     * 查询闹钟设备ID
     * @param clockId
     * @return
     */
    public String queryClocksDeviceId(String clockId){
        return clockDao.selectById(clockId).getDeviceId();
    }

    /**
     * insert
     * @param param
     */
    public void addClock(Clock param){
        clockDao.insert(param);
    }

    /**
     * update
     * @param param
     */
    public void editClock(Clock param){
        clockDao.updateById(param);

    }

    /**
     * delete   删除闹钟通过用户openid
     * @param openId
     */
    public void delClockByUser(String openId){
        LambdaUpdateWrapper<Clock> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(Clock::getOpenId, openId);
        clockDao.delete(updateWrapper);
    }

    /**
     * delete   删除闹钟
     * @param clockId
     */
    public void delClockById(String clockId){
        clockDao.deleteById(clockId);
    }

    /**
     * 根据deviceId查询设备是否已存在
     * @param deviceId
     * @return
     */
    public List<Clock> queryClockByDeviceId(String deviceId){
        LambdaQueryWrapper<Clock> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Clock::getDeviceId, deviceId);
        queryWrapper.eq(Clock::getDelFlag, 0);
        return clockDao.selectList(queryWrapper);
    }

    /**
     * 根据deviceId openid查询设备是否已存在
     * @param deviceId
     * @return
     */
    public List<Clock> queryClockByDeviceIdOpenid(String deviceId, String openid){
        LambdaQueryWrapper<Clock> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Clock::getDeviceId, deviceId);
        queryWrapper.eq(Clock::getOpenId, openid);
        queryWrapper.eq(Clock::getDelFlag, 0);
        return clockDao.selectList(queryWrapper);
    }

    /**
     * 更新设备的实时数据
     */
    public void refreshDeviceData(String payload, String status){
        log.info("更新设备数据的消息 =======" + payload);
        /*
         * 示例数据：
         * {
         *   "brightnessSetting": 5,
         *   "colorSetting": "00FF00",
         *   "hourlyBroadcastSwitch": 0,
         *   "deviceId": "24:ec:4a:02:a0:0c",
         *   "lightSwitch": 0,
         *   "setAlarmTime": {
         *     "clockSwitch1": "false",
         *     "clockSwitch2": "false",
         *     "clockSwitch3": "false",
         *     "clockTime1": "9:0",
         *     "clockTime2": "14:0",
         *     "clockTime3": "18:0"
         *   }
         * }
         */
        try {
            // 数据解析
            JSONObject jsonObject = JSONObject.parseObject(payload);
            Clock clockData = new Clock();
            clockData.setBrightnessSetting(jsonObject.getInteger("brightnessSetting"));
            clockData.setColorSetting(jsonObject.getString("colorSetting"));
            clockData.setHourlyBroadcastSwitch(jsonObject.getInteger("hourlyBroadcastSwitch"));
            clockData.setDeviceId(jsonObject.getString("deviceId"));
            clockData.setLightSwitch(jsonObject.getInteger("lightSwitch"));
            clockData.setSetAlarmTime(jsonObject.getString("setAlarmTime"));
            clockData.setRelay1Switch(jsonObject.getInteger("relay1Switch"));
            clockData.setRelay2Switch(jsonObject.getInteger("relay2Switch"));
            clockData.setRelay3Switch(jsonObject.getInteger("relay3Switch"));
            clockData.setRelay3Switch(jsonObject.getInteger("relay3Switch"));
            clockData.setPowerSwitchLeft(jsonObject.getInteger("powerSwitchLeft"));
            clockData.setPowerSwitchRight(jsonObject.getInteger("powerSwitchRight"));

            // 封装List<Map<String,Object>>类型的setAlarmTime字段
            JSONObject setAlarmTime = JSONObject.parseObject(jsonObject.getString("setAlarmTime"));
            List<Map<String,Object>> mapList = new ArrayList<>();
            Map<String, Object> map1 = new HashMap<>();
            map1.put("time", setAlarmTime.getString("clockTime1"));
            map1.put("enabled", setAlarmTime.getBoolean("clockSwitch1"));
            mapList.add(map1);
            Map<String, Object> map2 = new HashMap<>();
            map2.put("time", setAlarmTime.getString("clockTime2"));
            map2.put("enabled", setAlarmTime.getBoolean("clockSwitch2"));
            mapList.add(map2);
            Map<String, Object> map3 = new HashMap<>();
            map3.put("time", setAlarmTime.getString("clockTime3"));
            map3.put("enabled", setAlarmTime.getBoolean("clockSwitch3"));
            mapList.add(map3);
            clockData.setSetAlarmTime(mapList.toString());

            // 查询当前deviceId的设备是否存在，存在则更新数据，不存在则不操作
            List<Clock> clockList = queryClockByDeviceId(clockData.getDeviceId());
            if(clockList.size() > 0){// 更新数据
                clockList.forEach(e -> {
                    // 给参数数据加上clockId，通过clockId更新对应数据
                    clockData.setId(e.getId());
                    editClock(clockData);

                    // 给闹钟更新在线状态
                    long currentTime = System.currentTimeMillis();
                    // 更新最后接收时间
                    lastMessageTimeMap.put(e.getDeviceId(), currentTime);
                    // 更新数据库中的设备状态
                    updateDeviceStatus(e.getDeviceId(), status, currentTime);

                    // 发送闹钟在线状态给前端
//                    ClockInteractionBean config = new ClockInteractionBean();
//                    Map<String, Object> map = new HashMap<>();
//                    map.put("clockId", e.getId());
//                    map.put("status", 1);
//                    String topic = "/user/" + e.getOpenId() + "/alarmStatus";
//                    log.info("向前端发送闹钟在线状态信息: " + map.toString() + ",topic: " + topic);
//                    mqttMessageUtil.sendToMqtt(JSONObject.toJSONString(map), topic);
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 更新设备状态到数据库
     *
     * @param deviceId   设备ID
     * @param status    设备状态
     * @param timestamp 更新时间戳
     */
    public void updateDeviceStatus(String deviceId, String status, long timestamp) {
        Clock clock = new Clock();
        clock.setDeviceId(deviceId);
        clock.setOnLineState("在线".equals(status) ? 1 : 0);
        clock.setUpdateDate(new Timestamp(timestamp));
        clock.setUpdateBy("mqtt");
        LambdaUpdateWrapper<Clock> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(Clock::getDeviceId, deviceId);
        updateWrapper.set(Clock::getOnLineState, "在线".equals(status) ? 1 : 0);
        updateWrapper.set(Clock::getUpdateDate, new Timestamp(timestamp));
        updateWrapper.set(Clock::getUpdateBy, "mqtt");
        clockDao.update(clock, updateWrapper);
    }

    /**
     * 获取所有设备的最后接收时间
     *
     * @return 设备ID到最后接收时间的映射
     */
    public ConcurrentHashMap<String, Long> getLastMessageTimeMap() {
        return lastMessageTimeMap;
    }

    /**
     * 查询闹钟表里所有的city
     * @return  城市列表
     */
    public List<String> queryClockCitys(){
        LambdaQueryWrapper<Clock> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(Clock::getCity);
        queryWrapper.isNotNull(Clock::getCity).ne(Clock::getCity,"");
        queryWrapper.groupBy(Clock::getCity);
        List<Clock> clocks = clockDao.selectList(queryWrapper);
        List<String> cityList = new ArrayList<>();
        clocks.forEach(e -> {
            cityList.add(e.getCity());
        });
        return cityList;
    }

    /**
     * 查询闹钟表里所有的city,包括对应的deviceId串
     * @return  城市列表
     */
    public List<Map<String, String>> queryCityDeviceIds(){
        return clockDao.queryCityDeviceIds();
    }

    /**
     * 根据city查询所有该城市的闹钟
     * @return  城市列表
     */
    public List<Clock> queryClocksByCity(String city){
        LambdaQueryWrapper<Clock> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Clock::getCity, city);
        queryWrapper.eq(Clock::getDelFlag, 0);
        return clockDao.selectList(queryWrapper);
    }

}
